package com.example.demo.message;


import com.example.demo.constants.SubmissionSourceModuleConstant;
import com.example.demo.domain.entity.VojSubmissions;
import com.example.demo.init.ApplicationContextCache;
import com.example.demo.domain.exam.ExamSubmitLog;
import com.example.demo.mapper.VojSubmissionsMapper;
import com.example.demo.message.business.AbstractDataProcessBase;
import com.example.demo.message.business.BusinessProcessDataFactory;
import com.example.demo.service.ExamForUserService;
import lombok.RequiredArgsConstructor;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.jms.annotation.JmsListener;
import org.springframework.stereotype.Component;


import sun.rmi.runtime.Log;

import javax.annotation.Resource;
import javax.jms.JMSException;
import javax.jms.MapMessage;
import javax.jms.Message;
import javax.jms.MessageListener;
import java.io.File;

@Component
@RequiredArgsConstructor
public class MessageReceiver implements MessageListener {

    private static final Logger LOGGER = LoggerFactory.getLogger(MessageReceiver.class);

    @Resource
    private VojSubmissionsMapper vojSubmissionsMapper;



    private final ExamForUserService examForUserService;

    //    HttpServletResponse res;
    /* (non-Javadoc)
     * @see javax.jms.MessageListener#onMessage(javax.jms.Message)
     */
    @JmsListener(destination = "vojJudgeResultQueue")
    public void onMessage(Message message) {
        if (message instanceof MapMessage) {
            final MapMessage mapMessage = (MapMessage) message;
            try {
                String event = mapMessage.getString("event");
                Thread.sleep(100);  // 暂停0.1s 就能拿到数据
                long submissionId = mapMessage.getLong("submissionId");
                VojSubmissions vojSubmissions = vojSubmissionsMapper.selectById(submissionId);
                if (StringUtils.equals(vojSubmissions.getSourceModule(),"exam")) {
                    LOGGER.info("HERE");// TODO 考试模块记录
                    examForUserService.updateSubmissionLog(submissionId,vojSubmissions.getSubmissionJudgeScore(),ExamSubmitLog.EXAM_SUBMIT_LOG_NORMAL_STATUS,vojSubmissions);
                }


                BusinessProcessDataFactory factory = ApplicationContextCache.getApplicationContext().getBean(BusinessProcessDataFactory.class);
                AbstractDataProcessBase build = factory.build(vojSubmissions.getSourceModule());
                if (build != null) {
                    build.processData(vojSubmissions, mapMessage);
                }

                if ("ErrorOccurred".equals(event)) {
                    errorHandler(mapMessage);
                } else if ("AllTestPointsFinished".equals(event)) {
                    allTestPointsFinishedHandler(mapMessage);
                }

            } catch (Exception ex) {
                ex.printStackTrace();
            }
        }
    }

    /**
     * 处理评测机发生内部错误的消息.
     *
     * @param mapMessage - 消息队列中收到的MapMessage对象
     * @throws JMSException
     */
    private void errorHandler(MapMessage mapMessage) throws Exception {
        long submissionId = mapMessage.getLong("submissionId");
        examForUserService.updateSubmissionLog(submissionId, 0
                , ExamSubmitLog.EXAM_SUBMIT_LOG_ERROR_STATUS, null);
        System.out.println("OJ Exam 评测机内部出错，返回提交id：" + submissionId + "将更新提交的评测结果和日志。");
        vojSubmissionsMapper.updateJudgeResult("SE", "System Error. 评测机发生内部错误，请联系管理员！", submissionId);
    }


    /**
     * 处理评测机完成全部测试点的消息.
     *
     * @param mapMessage - 消息队列中收到的MapMessage对象
     * @throws JMSException
     */
    private void allTestPointsFinishedHandler(MapMessage mapMessage) throws Exception {
        // 根本不会执行此方法
        long submissionId = mapMessage.getLong("submissionId");
        VojSubmissions vojSubmissions = vojSubmissionsMapper.selectById(submissionId);
        if (SubmissionSourceModuleConstant.EXAM.equals(vojSubmissions.getSourceModule())){
            // TODO 考试模块记录
            examForUserService.updateSubmissionLog(submissionId, vojSubmissions.getSubmissionJudgeScore()
                    , ExamSubmitLog.EXAM_SUBMIT_LOG_NORMAL_STATUS, vojSubmissions);
        }
//        else if (SubmissionSourceModuleConstant.TRAIN.equals(vojSubmissions.getSourceModule())){
//            // TODO 培训模块记录
//
//        }
//        AbstractDataProcessBase build = factory.build(vojSubmissions.getSourceModule());
//        if (build != null) {
//            build.processData(vojSubmissions);
//        }
    }

    /**
     * 评测完成后, 清理所生成的文件.
     * @param file - 用于产生输出结果目录
     */
    public static Boolean deleteFile(File file) {
        //判断文件不为null或文件目录存在
        if (file == null || !file.exists()) {
            return false;
        }
        //获取目录下子文件
        File[] files = file.listFiles();
        //遍历该目录下的文件对象
        for (File f : files) {
            //判断子目录是否存在子目录,如果是文件则删除
            if (f.isDirectory()) {
                //递归删除目录下的文件
                deleteFile(f);
            } else {
                //文件删除
                f.delete();
                //打印文件名
            }
        }
        //文件夹删除
        file.delete();
        return true;
    }


}
